local AStarPath = require("app.map.AStarPath")
local BgMap = require("app.map.BgMap")
local MapPoint = require("app.map.MapPoint")
local PlayerController = require("app.figure.PlayerController")
-- 地图管理类
local MapController={}

function MapController:init()
    self.nCurFrame = 60
    self.mBgMap = nil
    self.mPlayerCtrl = nil --自己
    self.mPlayerCtrlList = {}
end

function MapController:switchMap(msg)
    self:unloadBgMap()
    if msg then
        self:loadBgMap(msg.stageid)
        self:addActor({pos = cc.p(msg.x,msg.y),id = msg.id})
    else
        self:loadBgMap(RoleData.player_info.stageid)
        self:addActor({pos = RoleData.player_info.pos,id = RoleData.player_info.rid})
    end
       
    self:startUpdateMap()
end

--载入地图
function MapController:loadBgMap(nMapID)
    self.mBgMap = BgMap.new(nMapID)
    return self.mBgMap
end

-- 卸载地图
function MapController:unloadBgMap()
    self:stopUpdateMap()
    for k,playerCtrl in pairs(self.mPlayerCtrlList) do  
        playerCtrl:cleanUp()
    end
    self.mPlayerCtrlList = {}
    if self.mBgMap then
       self.mBgMap:removeFromParent()
       self.mBgMap = nil
    end

    display.removeUnusedSpriteFrames()
end

--添加角色
function MapController:addActor(actorData)
    if self.mPlayerCtrlList[actorData.id] then
        self:ChangePos(actorData.id,actorData.pos)
        print("ERROR:actor %d already exist")
        return
    end
    local playerCtrl = PlayerController.new()
    if actorData.id == RoleData.player_info.rid then
        playerCtrl.bIsLeader = true
        self.mPlayerCtrl = playerCtrl        
    end
    local ccpos = MapPoint.grid2ccp(actorData.pos)
    local zOrder = MapController.getZOrder(ccpos)
    playerCtrl:getCurrPlayer():setPosition(ccpos)
    self.mBgMap:addChild(playerCtrl:getCurrPlayer(), zOrder)
    self.mPlayerCtrlList[actorData.id] = playerCtrl
end
function MapController:removeActor(id)
    if self.mPlayerCtrlList[id] then
        self.mPlayerCtrlList[id]:cleanUp()
        self.mPlayerCtrlList[id] = nil
    end
end
--改变位置  拉回
function MapController:ChangePos(id,grid,dir)
    local playerCtrl = self.mPlayerCtrlList[id]
    if playerCtrl then
        playerCtrl:forceTo(grid)
    end  
end
-- 更新地图计时器回调函数
function MapController:updateMap(dt)
    if DyActor:checkActorsWaiting() then
        local actor = DyActor:popActorsWaiting()
        if actor then
            self:addActor(actor)
        end
    end
    for k,playerCtrl in pairs(self.mPlayerCtrlList) do
        --更新人物位置
        playerCtrl:updatePlayerCtrl(dt)
        --更新地图
        if playerCtrl.bIsLeader then
            self:updateBgMap(playerCtrl)
        end 
    end    
end

function MapController:updateBgMap(playerCtrl)
    local x, y = playerCtrl:getCurrPlayer():getPosition()
    local pMap = cc.pSub(cc.p(display.cx, display.cy), cc.p(x, y))
    
    pMap.x = math.max(pMap.x, display.width-self.mBgMap.m_bgSize.width)
    pMap.y = math.max(pMap.y, display.height-self.mBgMap.m_bgSize.height)
    pMap.x = math.min(pMap.x, 0)
    pMap.y = math.min(pMap.y, 0)
    
    self.mBgMap:setPosition(pMap)
    
    self.mBgMap:updateImageDisplay()
end

function MapController:sendPlayerWalk(mappoint)
    NetEngine:sendMessage(ProtoCmd.ReqPlayerWalkMessage,{x=mappoint.x,y=mappoint.z,startTime=os.time()},false)
end

function MapController:detectReplaceMap(mappoint)
    local isDeliver,deliverId = self.mBgMap:checkDeliverGrid(mappoint)
    if  isDeliver then
        NetEngine:sendMessage(ProtoCmd.ReqTransmitByConfigMessage,{configId=deliverId},false)
    end
end
--主角移动
function MapController:goTo(mpoint)
    self.mPlayerCtrl:goTo(mpoint)
end
--其他角色的移动
function MapController:actorGoTo(actorid,grid)
    if actorid == RoleData.player_info.rid then
        return 
    end
    local playerCtrl = self.mPlayerCtrlList[actorid]
    if playerCtrl then
        playerCtrl:goTo(MapPoint.grid2mapp(grid))
    end
end

-- 开启更新地图计时器
function MapController:startUpdateMap()
    self:stopUpdateMap()
    if not self.scheduleMap then
        print("startUpdateMap")
		self.scheduleMap = cc.Director:getInstance():getScheduler():scheduleScriptFunc(handler(self, self.updateMap), 1/self.nCurFrame, false)
        print("startUpdateMap end")
	end
end

-- 关闭更新地图计时器
function MapController:stopUpdateMap()
    print("stopUpdateMap")
    if self.scheduleMap then
		cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.scheduleMap)
		self.scheduleMap = nil
	end
end

--获取路径
function MapController:getPath(beginMPoint, endMPoint)
    local dequeMPoint = AStarPath.findPathByAStar(
        self.mBgMap:getMapGrid(),
        self.mBgMap:getGridRow(),
        self.mBgMap:getGridCol(),
        beginMPoint, endMPoint)
    return dequeMPoint
end

function MapController:getCurMap()
    return self.mBgMap
end

function MapController:getCurPlayerCtrl()
    return self.mPlayerCtrl
end

function MapController:clean(args)
    
end

function MapController.getZOrder(point)
    return (-point.y / 10.0)
end

return MapController